/*
 * @Description  : Common definitions include pin assigns
 * @Version      : 0.1
 * @Company      : V-Think Development Team
 * @Author       : KiraVerSace@yeah.net
 * @Date         : 2020-07-09 14:44:50
 * @LastEditTime : 2022-03-30 01:14:19
 */
#include <xCommon.h>

uint32_t rebootCount  __attribute__((__section__(".noinit")));
/*----------------- freeRTOS callback -----------------*/
volatile uint32_t freeRTOSRunTimeCount = 0UL;
void freeRTOSAssertCalled(const char *fileName, int fileLine)	// 实现freeRTOS中的断言回调函数FreeRTOSConfig_Default.h/L214
{
	Serial.printf("freeRTOS Error:%s, %d\r\n", fileName, fileLine);
}

/*----------------- STM32Timer -----------------*/
STM32Timer freeRTOSTimer(TIM1);
const uint32_t FREERTOS_TIMER_PERIOD = 500;	// Unit
void freeRTOSTimerHandle(void)
{
	freeRTOSRunTimeCount++;
}

/*----------------- xShell -----------------*/
static Shell xShell;
static HardwareSerial *xShellSerial = &Serial;
static char xShellBuffer[1024];
static SemaphoreHandle_t xShellMutex;

static int16_t xShellWrite(char *data, uint16_t len)
{
	return xShellSerial->write((uint8_t *)data, len);
}

static int16_t xShellRead(char *data, uint16_t len)
{
	if(xShellSerial->available())
	{
		return xShellSerial->readBytes((uint8_t *)data, len);
	}
	else
	{
		return 0;
	}
}

static int xShellLock(Shell *shell)
{
    xSemaphoreTakeRecursive(xShellMutex, portMAX_DELAY);
    return 0;
}

static int xShellUnlock(Shell *shell)
{
    xSemaphoreGiveRecursive(xShellMutex);
    return 0;
}

static void xShellInit(void)
{
	xShellMutex = xSemaphoreCreateMutex();

	xShell.write  = xShellWrite;
	xShell.read   = xShellRead;
	xShell.lock   = xShellLock;
	xShell.unlock = xShellUnlock;

	shellInit(&xShell, xShellBuffer, sizeof(xShellBuffer));
}

void xShellRunTask(void)
{
	shellTask(&xShell);
}

/*----------------- xShell/xLog -----------------*/
Log xLog;

static void xLogWrite(char *buffer, int16_t len)
{
	if (xLog.shell)
	{
		shellWriteEndLine(xLog.shell, buffer, len);
	}
}

static void xLogInit(void)
{
	xLog.write  = xLogWrite;
	xLog.active = true;
	/*
	 * LOG_NONE   	// 无级别
	 * LOG_ERROR  	// 错误
	 * LOG_WRANING,	// 警告
	 * LOG_INFO  	// 消息
	 * LOG_DEBUG  	// 调试
	 * LOG_VERBOSE	// 冗余
	 * LOG_ALL    	// 所有日志
	 * 设置为 NONE 则没有任何日志输出
	 */
	xLog.level  = LOG_VERBOSE;

	logRegister(&xLog, &xShell);
}

static void hardwareInit(void)
{
	/* Set Interrupt Group Priority */
	HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

	/* IO 端口初始化 */
	pinMode(LED, 	OUTPUT);
	pinMode(BUZZER, OUTPUT);
	pinMode(BUTTON, INPUT);

	analogReadResolution(12);				// 设置 STM32 内部采集分辨率为 12-Bit

	Serial.begin(115200);

	if (freeRTOSTimer.attachInterruptInterval(FREERTOS_TIMER_PERIOD, freeRTOSTimerHandle))
	{
		Serial.printf("Starting  freeRTOSTimer OK, millis() = %d", millis());
	}
 	else
	{
		Serial.println("Can't set freeRTOSTimer. Select another freq. or timer");
	}
}


static void softwareInit(void)
{
	if (__HAL_RCC_GET_FLAG(RCC_FLAG_BORRST))
	{
		rebootCount = 0;
	}
	__HAL_RCC_CLEAR_RESET_FLAGS();

	rebootCount++;	// xHACK 每进入这个函数一次,则重启次数加一

	xShellInit();
	xLogInit();
}

void xCommonInit(void)
{
	hardwareInit();		// 必须先于软件初始化
	delay(10);			// 延时等待硬件初始化稳定
	softwareInit();
}

uint32_t readVref(void)
{
	return (__LL_ADC_CALC_VREFANALOG_VOLTAGE(analogRead(AVREF), LL_ADC_RESOLUTION_12B));
}

uint32_t readTempSensor(void)
{
	int32_t vRef = __LL_ADC_CALC_VREFANALOG_VOLTAGE(analogRead(AVREF), LL_ADC_RESOLUTION_12B);
	return (__LL_ADC_CALC_TEMPERATURE(vRef, analogRead(ATEMP), LL_ADC_RESOLUTION_12B));
}

uint32_t readButtonCell(void)
{
	int32_t vRef = __LL_ADC_CALC_VREFANALOG_VOLTAGE(analogRead(AVREF), LL_ADC_RESOLUTION_12B);
	/*The VBAT pin is internally connected to a bridge divider by 3*/
	return (__LL_ADC_CALC_DATA_TO_VOLTAGE(vRef, analogRead(AVBAT), LL_ADC_RESOLUTION_12B) * 3);
}
